package com.blog.util.fadada;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.blog.properties.FadadaProperties;
import com.blog.util.http.HttpUtil;
import com.fasc.open.api.bean.base.BaseRes;
import com.fasc.open.api.exception.ApiException;
import com.fasc.open.api.utils.ResultUtil;
import com.fasc.open.api.utils.crypt.FddCryptUtil;
import com.fasc.open.api.v5_1.client.CorpClient;
import com.fasc.open.api.v5_1.client.OpenApiClient;
import com.fasc.open.api.v5_1.client.ServiceClient;
import com.fasc.open.api.v5_1.req.corp.CorpIdentInfoReq;
import com.fasc.open.api.v5_1.req.corp.GetCorpAuthResourceUrlReq;
import com.fasc.open.api.v5_1.res.common.ECorpAuthUrlRes;
import com.fasc.open.api.v5_1.res.service.AccessTokenRes;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;

import java.util.*;

/**
 * @ClassName FaDaDaInit
 * @Destription 法大大相关处理封装类
 * @Author 天堂小野花
 * @Date 2025/7/12  14:24
 * @Version 1.0
 */
@Slf4j
public class FaDaDaInit {

    /**
     * 生成随机数
     */
    private String generateNonce() {
        // 生成一个随机数，最长32个字符
        return UUID.randomUUID().toString().replace("-", "").substring(0, 32);
    }
    //获取服务访问凭证
    public String createApiClient(FadadaProperties fadadaProperties) throws ApiException {
        //1.初始化客户端，注意填写正确的AppId和AppSecret
        OpenApiClient openApiClient = new OpenApiClient(fadadaProperties.getAppId(), fadadaProperties.getAppSecret(), fadadaProperties.getApiUrl());
         //corpClient = new CorpClient(openApiClient) ;
        ServiceClient serviceClient = new ServiceClient(openApiClient);
        BaseRes<AccessTokenRes> res = serviceClient.getAccessToken();
        ResultUtil.printLog(res, openApiClient.getJsonStrategy());
        return res.getData().getAccessToken();
    }
//    获取企业授权链接
    /*public boolean getCropUrl(FadadaProperties fadadaProperties,String accessToken) throws ApiException {
        GetCorpAuthResourceUrlReq getCorpAuthResourceUrlReq =  new GetCorpAuthResourceUrlReq() ;
        getCorpAuthResourceUrlReq.setClientCorpId(fadadaProperties.getClientCorpId()) ;
        getCorpAuthResourceUrlReq.setAccountName(fadadaProperties.getAccountName()); ;
        CorpIdentInfoReq corpIdentInfoReq =  new CorpIdentInfoReq() ;
        corpIdentInfoReq.setCorpName(fadadaProperties.getCorpName()); ;
        corpIdentInfoReq.setCorpIdentType(fadadaProperties.getCorpIdentType()); ;
        corpIdentInfoReq.setCorpIdentNo(fadadaProperties.getCorpIdentNo()); ;
        getCorpAuthResourceUrlReq.setCorpIdentInfo(corpIdentInfoReq) ;
        List<String> authScopes = new ArrayList<>() ;
        authScopes.add("ident_info") ;
        authScopes.add("seal_info") ;
        authScopes.add("organization") ;
        authScopes.add("template") ;
        authScopes.add("signtask_init") ;
        authScopes.add("signtask_info") ;
        getCorpAuthResourceUrlReq.setAuthScopes(authScopes) ;
        getCorpAuthResourceUrlReq.setAccessToken(accessToken) ;
        BaseRes<ECorpAuthUrlRes> res = corpClient.getCorpAuthUrl(getCorpAuthResourceUrlReq) ;
        //由于已经授权，此处仅判断一下就过
        if(res.getCode().equals("210002"))
            return true;
        else
            return false;
    }*/
//    上传本地文件
//    文件处理
//    创建签署任务（基于签署任务模板）
    public String createFasc(FadadaProperties fadadaProperties,String accessToken, Map<String, Object> bizContent) throws Exception {
        // 构造请求URL
        String url = fadadaProperties.getApiUrl()+ "sign-task/create-with-template";

        // Unix标准时间戳
        String timestamp = Long.toString(System.currentTimeMillis());

        // 构造请求头
        Map<String, String> headers = new HashMap<>();
        headers.put("X-FASC-App-Id", fadadaProperties.getAppId());
        headers.put("X-FASC-Sign-Type", "HMAC-SHA256");
        headers.put("X-FASC-Timestamp", timestamp);
        headers.put("X-FASC-Nonce", generateNonce());
        headers.put("X-FASC-AccessToken", accessToken);
        headers.put("X-FASC-Api-SubVersion", "5.1");
        headers.put("bizContent", JSON.toJSONString(bizContent));

        // 排序后的参数字符串，FddCryptUtil为法大大提供得签名工具类
        String paramToSignStr = FddCryptUtil.sortParameters(headers);
        // 计算之后得到签名字符串，该签名字符串需放到请求头中的X-FASC-Sign字段
        String signature = FddCryptUtil.sign(paramToSignStr, timestamp, fadadaProperties.getAppSecret());
        headers.put("X-FASC-Sign", signature);

        // 构造请求体
        Map<String, Object> requestParams = new HashMap<>();
        requestParams.put("bizContent", JSON.toJSONString(bizContent));

        // 发送POST请求
        String response = HttpUtil.post(url, requestParams, null,headers);

        // 解析返回结果
        JSONObject jsonObject = JSON.parseObject(response);
        JSONObject data = jsonObject.getJSONObject("data");
        String taskId = data.getString("signTaskId");

        return taskId;
    }
    //    获取参与方签署链接
    public Map<String, Object> getSignUrl(FadadaProperties fadadaProperties,String accessToken, Map<String, Object> bizContent) throws Exception {
    // 构造请求URL
    String url = fadadaProperties.getApiUrl() + "/sign-task/actor/get-url";

    // Unix标准时间戳
    String timestamp = Long.toString(System.currentTimeMillis());

    // 构造请求头
    Map<String, String> headers = new HashMap<>();
    headers.put("X-FASC-App-Id", fadadaProperties.getAppId());
    headers.put("X-FASC-Sign-Type", "HMAC-SHA256");
    headers.put("X-FASC-Timestamp", timestamp);
    headers.put("X-FASC-Nonce", generateNonce());
    headers.put("X-FASC-AccessToken", accessToken);
    headers.put("X-FASC-Api-SubVersion", "5.1");
    headers.put("bizContent", JSON.toJSONString(bizContent));

    // 排序后的参数字符串，FddCryptUtil为法大大提供得签名工具类
    String paramToSignStr = FddCryptUtil.sortParameters(headers);
    // 计算之后得到签名字符串，该签名字符串需放到请求头中的X-FASC-Sign字段
    String signature = FddCryptUtil.sign(paramToSignStr, timestamp, fadadaProperties.getAppSecret());
    headers.put("X-FASC-Sign", signature);
    // 构造请求体
    Map<String, Object> requestParams = new HashMap<>();
    requestParams.put("bizContent", JSON.toJSONString(bizContent));

    // 发送POST请求
    String response = HttpUtil.post(url, requestParams, null,headers);

            // 解析返回结果
    JSONObject jsonObject = JSON.parseObject(response);
    String code = jsonObject.getString("code");
    String msg = jsonObject.getString("msg");

    Map<String, Object> result = new HashMap<>();
    if ("100000".equals(code)) {
        JSONObject data = jsonObject.getJSONObject("data");
        String actorSignTaskUrl = data.getString("actorSignTaskUrl");
        String actorSignTaskEmbedUrl = data.getString("actorSignTaskEmbedUrl");

        result.put("actorSignTaskUrl", actorSignTaskUrl);
        result.put("actorSignTaskEmbedUrl", actorSignTaskEmbedUrl);
    } else {
        result.put("error", msg);
    }
    return result;
}
    //    获取签署文档下载地址

    //签署完成回调
    public  String fddEventCallback(FadadaProperties fadadaProperties, HttpHeaders headers, String bizContent)throws Exception{
        log.info("回调方法执行headers：{}", headers);
        log.info("回调方法执行bizContent：{}", bizContent);
        String appSecret = fadadaProperties.getAppSecret();

        // 获取请求头参数
        String appId = headers.getFirst("X-FASC-App-Id");
        String signType = headers.getFirst("X-FASC-Sign-Type");
        String sign = headers.getFirst("X-FASC-Sign");
        String timestamp = headers.getFirst("X-FASC-Timestamp");
        // 事件名称，开发者可以根据不同事件名称去解析bizContent的值，实现不同的逻辑
        String event = headers.getFirst("X-FASC-Event");
        String nonce = headers.getFirst("X-FASC-Nonce");
        // 验签
        Map<String, String> paramMap = new HashMap<>();
        paramMap.put("X-FASC-App-Id", appId);
        paramMap.put("X-FASC-Sign-Type", "HMAC-SHA256");
        paramMap.put("X-FASC-Timestamp", timestamp);
        paramMap.put("X-FASC-Nonce", nonce);
        paramMap.put("X-FASC-Event", event);
        paramMap.put("bizContent", bizContent);
        // 参数排序，ASCII码排序
        String sortParam = FddCryptUtil.sortParameters(paramMap);
        // 生成签名后可以进行校验
        String signature = FddCryptUtil.sign(sortParam, timestamp, appSecret);
        if (!signature.equals(sign)) {
            log.error("日志记录，签名失败");
            // 为了不重复接收该请求，建议这里返回success，返回success后这条消息法大大将中断重试回调机制
            return "{\"msg\":\"success\"}";
        }

        // 解析bizContent
        JSONObject bizContentJson = JSON.parseObject(bizContent);
        String eventTime = bizContentJson.getString("eventTime");
        String signTaskId = bizContentJson.getString("signTaskId");
        String signTaskStatus = bizContentJson.getString("signTaskStatus");

        // 业务处理
        if ("sign-task-signed".equals(event)) {
            // 处理签署任务完成的逻辑
            log.info("签署任务完成回调, 任务ID: {}, 时间: {}", signTaskId, eventTime);
            // 业务处理
            // 写入你自己的逻辑
            return "{\"msg\":\"success\"}";
        } else {
            log.warn("收到未处理的事件或状态, 事件: {}, 状态: {}", event, signTaskStatus);
            return null;
        }

    }
}
